package control

import (
	"net/http"
	_ "net/http/pprof"
	"recorder/internal"
	"recorder/log"

	"github.com/gorilla/websocket"
)

// Server handles http and websocket things
type Server struct {
	upgrader *websocket.Upgrader
	done     chan struct{}
	C        chan *Conn
}

func NewServer() *Server {
	return &Server{
		upgrader: new(websocket.Upgrader),
		done:     make(chan struct{}),
		C:        make(chan *Conn),
	}
}

func (s *Server) Run(config *internal.Config) {
	log.Info("listening to %v", config.Addr)
	http.HandleFunc("/control", s.HandleControl)
	//http.HandleFunc("/debug/pprof/", pprof.Index)
	//http.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
	//http.HandleFunc("/debug/pprof/profile", pprof.Profile)
	//http.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
	//http.HandleFunc("/debug/pprof/trace", pprof.Trace)
	//此处的代码我比较疑惑，ListenAndServe是阻塞的，那么还需要for么？
	for {
		select {
		case <-s.done:
			return
		default:
		}
		http.ListenAndServe(config.Addr, http.DefaultServeMux)
	}
}

func (s *Server) HandleControl(w http.ResponseWriter, r *http.Request) {
	// check if Server is closed
	select {
	case <-s.done:
		http.Error(w, "closed", http.StatusInternalServerError)
		return
	default:
	}

	connId := r.Header.Get("X-Conn-Id")
	if len(connId) == 0 {
		log.Warning("missing X-Conn-Id")
		http.Error(w, "missing X-Conn-Id", http.StatusBadRequest)
	}
	ws, err := s.upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Warning("upgrade websocket err=[%v]", err.Error())
		return
	}

	c := NewConn(ws, connId)
	log.Info("HandleControl the user connect ", c)

	go c.Run()
	select {
	case <-s.done:
		c.Close()
		return
	case s.C <- c:
	}
}

// Close will stop accept new connection and close existing connections
func (s *Server) Close() {
	close(s.done)
}
